﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using TomNet.Core;
using TomNet.App.Core.Contracts;
using TomNet.App.Model.DB;
using TomNet.App.Model.DTO;
using TomNet.AspNetCore.Data;
using TomNet.SqlSugarCore.Entity;
using Microsoft.Extensions.Logging;

namespace TomNet.App.Web.Controllers
{
    [Authorize]
    [Description("订单管理")]
    public class BusinessController : Common.BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly IBusinessContract _businessContract;
        private readonly IBusinessIncomeRunningsContract _incomeRunningsContract;
        private readonly Core.Contracts.Identity.IUsersContract _usersContract;

        public BusinessController(
            IUnitOfWork unitOfWork,
            IBusinessContract businessContract,
            IBusinessIncomeRunningsContract incomeRunningsContract,
            Core.Contracts.Identity.IUsersContract usersContract)
        {
            _unitOfWork = unitOfWork;
            _businessContract = businessContract;
            _incomeRunningsContract = incomeRunningsContract;
            _usersContract = usersContract;
        }

        public IActionResult Index()
        {
            return View();
        }

        #region IActionResult List()

        [Description("订单管理")]
        public IActionResult List()
        {
            return View();
        }

        #endregion

        #region IActionResult ListAsync(string keyword = "", int my = 0, int page = 1, int limit = 20)

        [HttpPost]
        public IActionResult ListAsync(string keyword = "", int my = 0, int page = 1, int limit = 20)
        {
            keyword = !string.IsNullOrWhiteSpace(keyword) ? keyword : "";

            List<int> businessIds = GetAfterBusinessIds(LoginUserId);

            var query = _businessContract.UnitOfWork.DbContext.Queryable<Model.DB.Business, Model.DB.Identity.Users>(
                (a, b) => a.UserId == b.Id)
                .Where((a, b) => (my == 0 && businessIds.Contains(a.Id)) || (my == 1 && a.UserId == LoginUserId))
                .Where((a, b) => keyword == "" || (a.ProductName.Contains(keyword) || b.UserName.Contains(keyword)))
                .OrderBy((a, b) => a.CreatedTime)
                .Select((a, b) => new ListAsyncModel
                {
                    Id = a.Id,
                    UserName = b.UserName,
                    ProductName = a.ProductName,
                    Hashrate = a.Hashrate.ToString(),
                    Kwh = a.Kwh,
                    ElectricCharge = a.ElectricCharge,
                    Price = a.Price,
                    Number = a.Number,
                    Amount = a.Amount,
                    CreatedTime = a.CreatedTime.ToString("yyyy-MM-dd"),
                    ActivationTime = a.ActivationTime.ToString("yyyy-MM-dd"),
                    State = a.State.ToString()
                });

            int total = 0;
            var list = query.ToPageList(page, limit, ref total);

            foreach(var entity in list)
            {
                entity.Hashrate = Convert.ToDecimal(entity.Hashrate).ConvertHashrate();
                entity.State = Common.Utility.BusinessStateString(Convert.ToInt32(entity.State));
            }

            var result = new LayuiPageResult<ListAsyncModel>
            {
                Code = 0,
                Msg = "Success",
                Count = total,
                Data = list.ToArray()
            };
            return Json(result);
        }

        public class ListAsyncModel
        {
            public int Id { get; set; }
            public string UserName { get; set; }
            public string ProductName { get; set; }
            public string Hashrate { get; set; }
            public decimal Kwh { get; set; }
            public decimal ElectricCharge { get; set; }
            public decimal Price { get; set; }
            public int Number { get; set; }
            public decimal Amount { get; set; }
            public string CreatedTime { get; set; }
            public string ActivationTime { get; set; }
            public string State { get; set; }
        }

        #endregion

        #region IActionResult OpenHandleAsync(string ids)

        [HttpPost]
        public IActionResult OpenHandleAsync(string ids)
        {
            var result = new AjaxResult("未知错误", Data.AjaxResultType.Error);

            int[] businessIds = ids.ConvertList<int>().ToArray();

            int count = _businessContract.Update(p => new Business { State = 1 }, p => businessIds.Contains(p.Id));
            if (businessIds.Length == count)
                result = new AjaxResult("操作成功。", Data.AjaxResultType.Success);
            else if (count != 0)
                result = new AjaxResult("操作成功（部分订单开机失败）", Data.AjaxResultType.Success);
            else
                result = new AjaxResult("操作失败。", Data.AjaxResultType.Error);

            return Json(result);
        }

        #endregion

        #region IActionResult CloseHandleAsync(string ids)

        [HttpPost]
        public IActionResult CloseHandleAsync(string ids)
        {
            var result = new AjaxResult("未知错误", Data.AjaxResultType.Error);

            int[] businessIds = ids.ConvertList<int>().ToArray();

            int count = _businessContract.Update(p => new Business { State = 2 }, p => businessIds.Contains(p.Id));
            if (businessIds.Length == count)
                result = new AjaxResult("操作成功。", Data.AjaxResultType.Success);
            else if (count != 0)
                result = new AjaxResult("操作成功（部分订单开机失败）", Data.AjaxResultType.Success);
            else
                result = new AjaxResult("操作失败。", Data.AjaxResultType.Error);

            return Json(result);
        }

        #endregion

        #region IActionResult IncomeList()

        [Description("订单收益列表")]
        public IActionResult IncomeList()
        {
            return View();
        }

        #endregion

        #region IActionResult IncomeListAsync(int businessId = -1, int page = 1, int limit = 20)

        [HttpPost]
        public IActionResult IncomeListAsync(int businessId = -1, int page = 1, int limit = 20)
        {
            List<int> businessIds = new List<int>();
            if (businessId <= 0)
                businessIds = GetAfterBusinessIds(LoginUserId);

            var query = _incomeRunningsContract.UnitOfWork.DbContext.Queryable<Model.DB.BusinessIncomeRunnings, Model.DB.Business, Model.DB.Identity.Users>(
                (a, b, c) => a.BusinessId == b.Id && b.UserId == c.Id)
                .Where((a, b, c) => businessIds.Contains(a.BusinessId))
                .OrderBy((a, b, c) => a.CreatedTime)
                .Select((a, b, c) => new
                {
                    a.Id,
                    c.UserName,
                    b.ProductName,
                    CreatedTime = a.CreatedTime.ToString("yyyy-MM-dd"),
                    a.RunTime,
                    a.Amount,
                    a.ElectricCharge,
                    a.ElectricChargeBTC
                });

            int total = 0;
            var list = query.ToPageList(page, limit, ref total);

            var result = new LayuiPageResult<dynamic>
            {
                Code = 0,
                Msg = "Success",
                Count = total,
                Data = list.ToArray()
            };
            return Json(result);
        }

        #endregion

        #region IActionResult CloseLog()

        [Description("关机记录")]
        public IActionResult CloseLog()
        {
            return View();
        }

        #endregion

        #region IActionResult CloseLogAlert()

        public IActionResult CloseLogAlert()
        {
            int businessId = -1;
            if (!int.TryParse(Request.Query["businessId"], out businessId))
                businessId = -1;

            ViewData["businessId"] = businessId;
            return View();
        }

        #endregion

        #region IActionResult CloseLogAsync(int businessId = -1,int page = 1, int limit = 20)

        [HttpPost]
        public IActionResult CloseLogAsync(int businessId = -1,int page = 1, int limit = 20)
        {
            List<int> businessIds = GetAfterBusinessIds(LoginUserId);

            var query = _businessContract.UnitOfWork.DbContext.Queryable<Model.DB.BusinessOnOffRunnings, Model.DB.Business, Model.DB.Identity.Users>(
                (a, b, c) => a.BusinessId == b.Id && b.UserId == c.Id)
                .Where((a, b, c) => a.State == 1)
                .Where((a, b, c) => (businessId == -1 && businessIds.Contains(a.Id)) || (businessId > 0 && a.BusinessId == businessId))
                .OrderBy((a, b, c) => a.OffTime)
                .Select((a, b, c) => new CloseLogAsyncModel
                {
                    Id = a.Id,
                    UserName = c.UserName,
                    BusinessId = a.BusinessId,
                    ProductName = b.ProductName,
                    OffTime = a.OffTime.ToString("yyyy-MM-dd HH:mm:ss")
                });

            int total = 0;
            var list = query.ToPageList(page, limit, ref total);
            
            var result = new LayuiPageResult<CloseLogAsyncModel>
            {
                Code = 0,
                Msg = "Success",
                Count = total,
                Data = list.ToArray()
            };
            return Json(result);
        }

        public class CloseLogAsyncModel
        {
            public int Id { get; set; }

            public string UserName { get; set; }

            public int BusinessId { get; set; }

            public string ProductName { get; set; }

            public string OffTime { get; set; }
        }

        #endregion

        public IActionResult ElectricCharge()
        {
            return View();
        }

        [HttpPost]
        public IActionResult ElectricChargeAsync(int type = 0, int page = 1, int limit = 20)
        {
            List<int> userIds = GetAfterUserIds(LoginUserId);

            var query = _usersContract.UnitOfWork.DbContext.Queryable<Model.DB.UserElectricity, Model.DB.Identity.Users>(
                (a, b) => a.UserId == b.Id)
                .Where((a, b) => userIds.Contains(b.Id))
                .Select((a, b) => new
                {
                    a.Id,
                    b.UserName,
                    Type = a.Amount > 0 ? "充值" : "扣款",
                    a.Amount,
                    a.CreatedTime
                }) ;
            
            switch (type)
            {
                case 1:
                    query.Where(a => a.Amount > 0);
                    break;
                case 2:
                    query.Where(a => a.Amount<=0);
                    break;
            }

            int total = 0;
            var list = query.ToPageList(page, limit, ref total);

            var result = new LayuiPageResult<dynamic>
            {
                Code = 0,
                Msg = "Success",
                Count = total,
                Data = list.ToArray()
            };
            return Json(result);
        }



        #region List<int> GetAfterBusinessIds(int userId) 获取指定用户所有下级用户的订单。

        /// <summary>
        /// 获取指定用户所有下级用户的订单。
        /// </summary>
        /// <param name="userId">用户Id</param>
        /// <returns></returns>
        private List<int> GetAfterBusinessIds(int userId)
        {
            //用户角色表
            //1超级管理员 2公司业务 3接口商 4接口商下的业务员 5代理商 6代理商下的业务员 7用户

            List<int> result = new List<int>();

            int roleId = _usersContract.Entities.AsQueryable().Where(p => p.Id == userId).Select(p => p.RoleID).First();
            if (roleId <= 0)
                return result;

            var query = _businessContract.UnitOfWork.DbContext.Queryable<Model.DB.Business, Model.DB.Identity.UserMap>(
                (a, b) => a.UserId == b.UserId)
                .Where((a, b) => (roleId == 1 && b.SuperId == userId)
                    || (roleId == 2 && b.SuperSalesmanId == userId)
                    || (roleId == 3 && b.InterfaceId == userId)
                    || (roleId == 4 && b.InterfaceSalesmanId == userId)
                    || (roleId == 5 && b.AgentId == userId)
                    || (roleId == 6 && b.AgentSalesmanId == userId))
                .OrderBy((a, b) => a.CreatedTime)
                .Select((a, b) => a.Id);
            
            result = query.ToList();
            return result;
        }

        #endregion

        #region List<int> GetAfterUserIds(int userId) 获取指定用户所有下级的用户Id。

        /// <summary>
        /// 获取指定用户所有下级的用户Id。
        /// </summary>
        /// <param name="userId">用户Id</param>
        /// <returns></returns>
        private List<int> GetAfterUserIds(int userId)
        {
            List<int> result = new List<int>();

            int roleId = _usersContract.Entities.AsQueryable().Where(p => p.Id == userId).Select(p => p.RoleID).First();
            if (roleId <= 0)
                return result;

            var query = _businessContract.UnitOfWork.DbContext.Queryable<Model.DB.Identity.Users, Model.DB.Identity.UserMap>(
                (a, b) => a.Id == b.UserId)
                .Where((a, b) => (roleId == 1 && b.SuperId == userId)
                    || (roleId == 2 && b.SuperSalesmanId == userId)
                    || (roleId == 3 && b.InterfaceId == userId)
                    || (roleId == 4 && b.InterfaceSalesmanId == userId)
                    || (roleId == 5 && b.AgentId == userId)
                    || (roleId == 6 && b.AgentSalesmanId == userId))
                .OrderBy((a, b) => a.CreatedTime)
                .Select((a, b) => a.Id);

            result = query.ToList();
            return result;
        }

        #endregion
    }
}